#include "Room.h"

using namespace car;

Room::Room(void)
{
	mRoomState = RoomStateWaiting;
	mHostId = 0;
	mNumForces = 2;
}

Room::Room( unsigned int roomId, unsigned char maxPlayerNumber )
{
	mRoomState = RoomStateWaiting;
	mRoomId = roomId;
	mHostId = 0;
	mMaxPlayerNumber = maxPlayerNumber;
	mNumForces = 2;
	clearPlayerList();
	mGame = NULL;
}

Room::Room( unsigned int roomId, unsigned int hostId, unsigned char maxPlayerNumber )
{
	mRoomState = RoomStateWaiting;
	mRoomId = roomId;
	mHostId = hostId;
	mMaxPlayerNumber = maxPlayerNumber;
	mNumForces = 2;
	clearPlayerList();
	mGame = NULL;
}

Room::~Room(void)
{
	clearRoom();
}

bool Room::addPlayer( Player * player )
{
	if( mPlayerList.size() >= mMaxPlayerNumber )
		return false;
	if( mRoomState != RoomStateWaiting && mRoomState != RoomStateGameEnd )
		return false;
	unsigned char forceId = 1;
	std::list<Player *>::iterator itr;
	for( itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr )
	{
		if( ( *itr )->getForceId() != forceId )
			break;
		forceId++;
	}
	player->setForceId( forceId );
	mPlayerList.insert( itr, player );	

	return true;
}

bool Room::removePlayer( unsigned int playerId )
{
	for( std::list<Player *>::iterator itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr )
	{
		if( ( *itr )->getPlayerId() == playerId )
		{
			mPlayerList.remove( *itr );
			return true;
		}
	}

	return false;
}

bool Room::hasPlayer( unsigned int playerId )
{
	for( std::list<Player *>::iterator itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr )
	{
		if( ( *itr )->getPlayerId() == playerId )
			return true;
	}

	return false;
}

bool Room::spreadPacket( const unsigned char data[], int size ) {
	for( std::list<Player *>::iterator itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr )
	{
		if( ( *itr )->sendPacket( data, size ) )
		{
			printf( "send packet successfully\n" );
			( *itr )->setPacketSent( true );
		}
		else
		{
			printf( "send packet failed\n" );
		}
	}

	return true;
}

bool Room::startGame()
{
	if( mRoomState == RoomStateWaiting )
	{
		if( mGame )
		{
			delete mGame;
			mGame = NULL;
		}
		mGame = new Game();
		for( std::list<Player *>::iterator itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr )
		{
			Player * player = ( *itr );
			if( player )
				player->setPlayerState( PlayerStateLoadingGame );
		}
		mRoomState = RoomStateLoadingGame;
		return true;
	}
	return false;
}

void Room::stopGame()
{
	if( mGame )
	{
		delete mGame;
		mGame = NULL;
	}
	mRoomState = RoomStateGameEnd;
}

void Room::checkPlayerLoadingProgress()
{
	
	if( mRoomState == RoomStateLoadingGame )
	{
		bool isAllPlayersReady = true;
		for( std::list<Player *>::iterator itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr )
		{
			Player * player = ( *itr );
			if( !player || player->getPlayerState() != PlayerStateLoadingGameComplete )
			{
				isAllPlayersReady = false;
				break;
			}			
		}
		if( isAllPlayersReady )
		{
			for( std::list<Player *>::iterator itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr )
			{
				Player * player = ( *itr );
				if( player )
					player->setPlayerState( PlayerStateInGame );	
			}
			mRoomState = RoomStateInGame;
		}
	}
	else if( mRoomState == RoomStateGameEnd )
	{
		bool isAllPlayersInRoom = true;
		for( std::list<Player *>::iterator itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr )
		{
			Player * player = ( *itr );
			if( !player || player->getPlayerState() != PlayerStateInRoom )
			{
				isAllPlayersInRoom = false;
				break;
			}			
		}
		if( isAllPlayersInRoom )
		{
			mRoomState = RoomStateWaiting;
		}
	}
}

void Room::clearPlayerList()
{
	for( std::list<Player *>::iterator itr = mPlayerList.begin(); itr != mPlayerList.end(); ++itr )
		{
			Player * player = ( *itr );
			if( player )
			{
				player->leaveRoom();
				mPlayerList.remove( player );
			}
		} 
}

void Room::clearRoom()
{
	stopGame();
	clearPlayerList();
}